package com.xu.cloud.common.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xu.cloud.common.api.ApiVersionRequestMappingHandlerMapping;
import com.xu.cloud.common.idempotent.IdempotentHandlerInterceptor;
import com.xu.cloud.common.idempotent.IdempotentIfc;
import com.xu.cloud.common.process.support.JavaBeanRequestResponseMethodProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.List;

/**
 * WebMvc Config
 *
 * @author xuguan
 * @since 2025/2/20
 */
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@Configuration
public class WebConfig {
    @Bean
    public JavaBeanRequestResponseMethodProcessor javaBeanRequestResponseMethodProcessor(List<HttpMessageConverter<?>> converters,
                                                                                         List<RequestBodyAdvice> requestBodyAdvice,
                                                                                         List<ResponseBodyAdvice<?>> responseBodyAdvice,
                                                                                         ObjectMapper objectMapper) {
        return new JavaBeanRequestResponseMethodProcessor(converters, requestBodyAdvice, responseBodyAdvice, objectMapper);
    }

    @Configuration
    public static class WebMvcConfig implements WebMvcConfigurer {
        private final JavaBeanRequestResponseMethodProcessor javaBeanRequestResponseMethodProcessor;
        private final IdempotentIfc idempotentIfc;

        public WebMvcConfig(JavaBeanRequestResponseMethodProcessor javaBeanRequestResponseMethodProcessor, IdempotentIfc idempotentIfc) {
            this.javaBeanRequestResponseMethodProcessor = javaBeanRequestResponseMethodProcessor;
            this.idempotentIfc = idempotentIfc;
        }

        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 幂等性处理拦截器
            final IdempotentHandlerInterceptor idempotentHandlerInterceptor = new IdempotentHandlerInterceptor(idempotentIfc);
            registry.addInterceptor(idempotentHandlerInterceptor);
        }

        @Override
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
            resolvers.add(javaBeanRequestResponseMethodProcessor);
        }

        @Override
        public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
            handlers.add(javaBeanRequestResponseMethodProcessor);
        }
    }

    @Configuration
    public static class WebMvcRegistry implements WebMvcRegistrations {
        @Override
        public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
            return new ApiVersionRequestMappingHandlerMapping();
        }
    }
}
